package leetCode.hw.math;

import java.util.Stack;

public class HJ54Solution implements HJ54 {


    /**
     * 表达式计算
     * @param str
     * @return
     */
    @Override
    public double calNum(String str) {
        str = str.replaceAll("[{,\\[]","(");
        str = str.replaceAll("[},\\]]",")");
        int n = str.length();
        // num1为已经计算好的部分值,num2为正在计算的值
        double num1 = 0, num2 = 1;
        // o1==1(+) o1==-1(-)
        // o2==1(*) o2==-1(/)
        double o1 = 1, o2 = 1;
        Stack<Double> stack = new Stack<>();
        for(int i=0;i<n;i++) {
            char c = str.charAt(i);
            // 如果遇到数字,读取数字存入num2中
            if(Character.isDigit(c)) {
                int cur = 0;
                while(i<n&&Character.isDigit(str.charAt(i))){
                    cur = cur * 10 + (str.charAt(i)-'0');
                    i++;
                }
                i--;
                num2 = o2==1?num2*cur:num2/cur;
                continue;
            }
            switch (c) {
                case '*':
                case '/':
                    o2 = c=='*'?1:-1;
                    break;
                case '(':
                    stack.push(num1);
                    stack.push(o1);
                    stack.push(num2);
                    stack.push(o2);
                    num1 = 0;
                    o1 = 1;
                    num2 = 1;
                    o2 = 1;
                    break;
                case ')':
                    double cur = num1 + o1 * num2;
                    o2 = stack.pop();
                    num2 = stack.pop();
                    o1 = stack.pop();
                    num1 = stack.pop();
                    num2 = o2 == 1?num2*cur:num2/cur;
                    break;
                case '+':
                case '-':
                    // 如果减号出现在计算式的开始
                    if(c=='-'&&(i==0||str.charAt(i-1)=='('||str.charAt(i-1)=='*'||str.charAt(i-1)=='/')) {
                        o1 = -1;
                        continue;
                    }
                    num1 = num1 + o1 * num2;
                    o1  = (c=='+'?1:-1);
                    num2 = 1;
                    o2 = 1;
            }
        }
        return num1+o1*num2;
    }
}
